/*
 * AplCadastroInterno.java
 * 
 * Projeto: Kruskal - SRAC
 * LEDS - Laboratório de Engenharia e Desenvolvimento de Software
 * IFES - Instituto Federal do Espírito Santo - Campus Serra.
 */
package srac.controleatividades.cgt;

import java.util.ArrayList;
import java.util.List;
import srac.controleatividades.cdp.*;
import srac.controleatividades.cgd.*;
import util.utilitarioExceptions.SracException;
import util.utilitarioPersistencia.DAO;
import util.utilitarioPersistencia.DAOFactory;

public class AplCadastroInterno {

    private DAO apDaoCategoria = DAOFactory.obterDAO(Categoria.class);
    private DAO apDaoTipoAtividade = DAOFactory.obterDAO(TipoAtividade.class);
    private DAO apDaoUsuario = DAOFactory.obterDAO(Usuario.class);
    private DAO apDaoFuncionario = DAOFactory.obterDAO(Funcionario.class);
    private DAO apDaoAluno = DAOFactory.obterDAO(Aluno.class);

    private AplCadastroInterno() {
    }
    private static AplCadastroInterno instance = null;

    public static AplCadastroInterno getInstance() {
        if (instance == null) {
            instance = new AplCadastroInterno();
        }
        return instance;
    }
    
    /**
     * Inclui uma nova Categoria
     * @param args
     * @return A categoria incluida ou Null caso haja algum erro
     * @throws Exception
     */
    public Categoria incluirCategoria(ArrayList<Object> args) throws  Exception {
        Categoria categoria = new Categoria();

        categoria.setNome((String) args.get(0));

        return (Categoria) apDaoCategoria.salvar(categoria);
    }
    
    /**
     * Altera uma Categoria
     * @param args
     * @return A Categoria Alterada ou Null caso haja algum erro
     * @throws Exception
     */

    public Categoria alterarCategoria(Categoria categoria) throws Exception {
        return (Categoria) apDaoCategoria.salvar(categoria);
    }
    
    /**
     * Apaga a Catregoria
     * @param categoria
     * @return Verdadeiro caso seja possível apagar a Categoria ou Falso caso contrário
     * @throws Exception
     */

    public boolean apagarCategoria(Categoria categoria) throws Exception {
        if (!this.obterTipoAtividades(categoria).isEmpty()) {
            return false;
        }

        apDaoCategoria.excluir(categoria);
        return true;
    }
    /**
     * Obtem todas as Categorias cadastradas
     * @return Uma lista de Categorias ou Null caso haja algum erro
     * @throws Exception
     */

    public List<Categoria> obterCategorias() throws Exception {
        return (List<Categoria>) apDaoCategoria.obter(Categoria.class);
    }
    
    /**
     * Obtem as Atividades com o 'nome'
     * @param nome
     * @return Uma lista de Categorias ou Null caso haja algum erro
     * @throws Exception 
     */
    
     public List<Categoria> obterCategorias(String nome) throws  Exception {
        return ((CategoriaDAOJPA) apDaoCategoria).obterCategoria(nome);
    }
     
     /**
     * Inclui um novo Tipo Atividade
     * @param args
     * @return O Tipo Atividade incluido ou Null caso haja algum erro
     * @throws Exception 
     */
    
    public TipoAtividade incluirTipoAtividade(ArrayList<Object> args) throws  Exception {
        TipoAtividade tipoAtividade = new TipoAtividade();

        tipoAtividade.setCategoria((Categoria) args.get(0));
        tipoAtividade.setCodigo((Integer) args.get(1));
        tipoAtividade.setCreditos((Integer) args.get(2));
        tipoAtividade.setUnidadeTempo((String) args.get(3));
        tipoAtividade.setDescricao((String) args.get(4));
        

        return (TipoAtividade) apDaoTipoAtividade.salvar(tipoAtividade);

    }
    
    /**
     * Altera um Tipo Atividade
     * @param args
     * @return O Tipo Atividade Alterado ou Null caso haja algum erro
     * @throws Exception 
     */

    public TipoAtividade alterarTipoAtividade(TipoAtividade tipoAtividade) throws Exception {
        return (TipoAtividade) apDaoTipoAtividade.salvar(tipoAtividade);
    }
    
    /**
     * Apaga um Tipo Atividade
     * @param tipoAtividade
     * @return Verdadeiro caso seja possível ou Falso caso contrário
     * @throws Exception 
     */

    public boolean apagarTipoAtividade(TipoAtividade tipoAtividade) throws Exception {
        //validacao
        if (!AplAtividade.getInstance().obterAtividadesComplementares(tipoAtividade).isEmpty()) {
            return false;
        }
        //exclusao
        apDaoTipoAtividade.excluir(tipoAtividade);
        return true;
    }
    
    /**
     * Obtem todos os Tipos Atividades cadastrados 
     * @return Uma lista de Tipos Atividades ou Null caso haja algum erro
     * @throws Exception 
     */

    public List<TipoAtividade> obterTipoAtividades() throws Exception {
        return (List<TipoAtividade>) apDaoTipoAtividade.obter(TipoAtividade.class);
    }
    
    /**
     * Obtem todos os Tipos Atividades cadastrados  da Categoria
     * @param c
     * @return Uma lista de Tipos Atividades ou Null caso haja algum erro
     * @throws Exception 
     */

    public List<TipoAtividade> obterTipoAtividades(Categoria c) {
        return ((TipoAtividadeDAOJPA) apDaoTipoAtividade).obterTipoAtividade(c);
    }
    
    /**
     * Obtem todos os Tipos Atividades cadastrados com o 'nome' e 'codigo'
     * @param c
     * @return Uma lista de Tipos Atividades ou Null caso haja algum erro
     * @throws Exception 
     */
    
    public List<TipoAtividade> obterTipoAtividades(String nome, Integer codigo) {
        return ((TipoAtividadeDAOJPA) apDaoTipoAtividade).obterTipoAtividade(nome, codigo);
    }
    
    
    public List<TipoAtividade> obterTipoAtividades(Integer c) {
        return ((TipoAtividadeDAOJPA) apDaoTipoAtividade).obterTipoAtividade(c);
    }
    
    /**
     * Verifica se ja existe algum tipoAtividade cadastrado com o mesmo nome ou codigo.
     * @param nome
     * @param codigo
     * @return Verdadeiro se existe ou Falso senão existe
     * @throws Exception 
     */
    
    public boolean verificaExistencia(String nome, Integer codigo) throws Exception
    {
        if(!(obterTipoAtividades(nome, codigo).isEmpty()))
        {
            return true;
        }
        return false;
    }
    
    /**
     * Verifica se ja existe alguma categoria cadastrada com o mesmo nome.
     * @param nome
     * @return Verdadeiro se existe ou Falso senão existe
     * @throws Exception 
     */
    
    public boolean verificaExistencia(String nome) throws Exception
    {
        if(!(obterCategorias(nome).isEmpty()))
        {
            return true;
        }
        return false;
    }
    
        
    /*aqui começa o código de inclusão do usuário*/
    
    /**
     * Inclui um novo usuário, aluno ou funcionário.
     * @param args
     * @return
     * @throws SracException
     * @throws Exception 
     */
    
    public Funcionario incluirFuncionario(ArrayList<Object> args) throws Exception {
        Usuario usuario = new Usuario();
        Funcionario f = new Funcionario();
        f.setNome((String) args.get(0));
        f.setSiape((String) args.get(1));
        usuario.setTipo((TipoUsuario)args.get(3));
        usuario.setLogin((String) args.get(1));
        usuario.setSenhaCriptografar((String) args.get(2));
        usuario.setAtivo(true);
        apDaoUsuario.salvar(usuario);
        f.setUsuario(usuario);
        return (Funcionario) apDaoFuncionario.salvar(f);
    }
    
    public Aluno incluirAluno(ArrayList<Object> args) throws Exception {
        Aluno a = new Aluno();
        Usuario usuario = new Usuario();
        a.setNome((String) args.get(0));
        a.setEmail((String) args.get(1));
        a.setMatricula((String) args.get(2));
        a.setCpf((String) args.get(3));
        a.setStatusSubmissao((StatusSubmissao) args.get(5));
        usuario.setTipo(TipoUsuario.ALUNO);
        usuario.setLogin((String) args.get(2));
        usuario.setSenhaCriptografar((String) args.get(4));
        usuario.setAtivo(true); 
        apDaoUsuario.salvar(usuario);
        a.setUsuario(usuario);
        return (Aluno) apDaoAluno.salvar(a);
    }

    /**
     * Alterar um usuário do tipo funcionário
     * @param funcionario
     * @return
     * @throws Exception 
     */
    public Funcionario alterarFuncionario(Funcionario funcionario) throws Exception {
        apDaoUsuario.salvar(funcionario.getUsuario());
        return (Funcionario) apDaoFuncionario.salvar(funcionario);
    }
    
    /**
     * Altera um usuário do tipo aluno
     * @param aluno
     * @return
     * @throws Exception 
     */
    public Aluno alterarAluno(Aluno aluno) throws Exception {
        apDaoUsuario.salvar(aluno.getUsuario());
        return (Aluno) apDaoAluno.salvar(aluno);
    }

    /**
     * Exclui um usuário do tipo funcionário
     * @param funcionario
     * @return
     * @throws Exception 
     */
    public boolean apagarFuncionario(Funcionario funcionario) throws Exception {
        //TODO validacao, 
        
        //exclusao
        apDaoFuncionario.excluir(funcionario);
        apDaoUsuario.excluir(funcionario.getUsuario());
        return true;
    }
    
    /**
     * Exclui um funcionário do tipo Aluno
     * @param aluno
     * @return
     * @throws Exception 
     */
    public boolean apagarAluno(Aluno aluno) throws Exception {
        if (!AplAtividade.getInstance().obterAtividadesComplementares(aluno).isEmpty()) {
            return false;
        }
        //exclusao
        apDaoFuncionario.excluir(aluno);
        apDaoUsuario.excluir(aluno.getUsuario());
        return true;
    }

    /**
     * Obtém a listade todos os usuários cadastrados.
     * @return
     * @throws SracException
     * @throws Exception 
     */
    public List<Usuario> obterUsuarios() throws SracException, Exception {
        return (List<Usuario>) apDaoUsuario.obter(Usuario.class);
    }
    
    /**
     * Obtpem ums lista de todos os usuários do TipoUsuario t
     * @param t
     * @return 
     */
    public List<Usuario> obterUsuarios(TipoUsuario t) {
        return ((UsuarioDAOJPA) apDaoUsuario).obterUsuarios(t);
    }
    
    /**
     * Obtém um lista com usuário cujo login seja igual login
     * @param login
     * @return 
     */
    public List<Usuario> obterUsuarios(String login) {
        return ((UsuarioDAOJPA) apDaoUsuario).obterUsuarios(login);
    }
    
    /**
     * Verifica a existência de um usuário com login, matrícula ou siape já cadastrados.
     * @param login
     * @param matOuSiape
     * @param t
     * @return
     * @throws Exception 
     */
    public boolean verificaExistenciaUsuario(String matOuSiape) throws Exception
    {
        if(obterUsuarios(matOuSiape).isEmpty())
        {
            return false;
        }
        return true;
        
    }
    
    public List<Funcionario> obterFuncionario() throws SracException, Exception {
        return (List<Funcionario>) apDaoFuncionario.obter(Funcionario.class);
    }
    
    public List<Funcionario> obterFuncionario(String nome) {
        return ((FuncionarioDAOJPA) apDaoUsuario).obterFuncionario(nome);
    }
    public List<Funcionario> obterFuncionarioPorSiape(String siape) {
        return ((FuncionarioDAOJPA) apDaoUsuario).obterFuncionarioPorSiape(siape);
    }
    
    public List<Aluno> obterAluno() throws SracException, Exception {
        return (List<Aluno>) apDaoAluno.obter(Aluno.class);
    }
    
    public List<Aluno> obterAluno(String nome) {
        return ((AlunoDAOJPA) apDaoAluno).obterAluno(nome);
    }
    public List<Aluno> obterAlunoPorMatricula(String matricula) {
        return ((AlunoDAOJPA) apDaoAluno).obterAlunoPorMatricula(matricula);
    }
    
    public Aluno obterAluno(Usuario u)
    {
        return ((AlunoDAOJPA) apDaoAluno).obterAluno(u);
    }
    
    public void ativarDesativarUsuario(Usuario u, boolean b) throws Exception
    {
        u.setAtivo(b);
        apDaoUsuario.salvar(u);
    }
    

}
